package com.rdxer.service;


import com.rdxer.api.para.LoginPara;
import com.rdxer.config.AppConfig;
import com.rdxer.core.base.CRUDExServiceInterface;
import com.rdxer.core.ex.ObjectEx;
import com.rdxer.core.exception.exceptions.BaseException;
import com.rdxer.core.security.JWTConfiguration;
import com.rdxer.core.utils.IdWorker;
import com.rdxer.dataview.AuthTokenDV;
import com.rdxer.model.Account;
import com.rdxer.repository.AccountRepository;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class AccountService implements CRUDExServiceInterface<Account, String> {
    @Autowired
    AccountRepository repository;
    @Autowired
    PasswordEncoder passwordEncoder;
    @Autowired
    IdWorker idWorker;
    @Autowired
    private JWTConfiguration jwtConfiguration;


    @Override
    public @NotNull AccountRepository getRepository() {
        return repository;
    }


    public Account findByName(String name) {
        return getRepository().findAccountByUsername(name);
    }


    public List<Account> findByNameOrEmailOrPhone(String value) {
        return getRepository().findAccountsByUsernameOrTelOrEmail(value, value, value);
    }
    public List<Account> findByNameOrId(String username) {
        return getRepository().findByUsernameOrId(username, username);
    }


    public Account register(Account model) {

        checkByAdd(model);

        if (StringUtils.isEmpty(model.getAvatar())) {
            model.setAvatar(AppConfig.avatarUrlPlaceholder);
        }


        if (ObjectUtils.isEmpty(model.getEntryDate())) {
            model.setEntryDate(System.currentTimeMillis());
        }
        //  ID 客户端上传 不进行生成
        if (ObjectUtils.isEmpty(model.getId())) {
            model.setId(idWorker.nextIdHex());
        }

        String encodepwd = passwordEncoder.encode(model.getPassword());
        model.setPassword(encodepwd);

        model.setCreatedDate(System.currentTimeMillis());
        model.setUpdateDate(System.currentTimeMillis());
        model.setRoles("student");

        Account account = getRepository().saveAndFlush(model);


        return account;
    }

    public Account registerAccount(Account model) {
        if (!StringUtils.isEmpty(model.getId())) {
            Optional<Account> account = repository.findById(model.getId());
            if (account.isEmpty()) {
                throw BaseException.ofBadRequest("学号/教师号已被注册");
            }
        }
        if (!StringUtils.isEmpty(model.getUsername())) {
            Account byUsername = repository.findAccountByUsername(model.getUsername());
            if (byUsername != null) {
                throw BaseException.ofBadRequest("此账号已存在");
            }
        }
        //  ID 客户端上传 不进行生成
        if (ObjectUtils.isEmpty(model.getId())) {
            throw BaseException.ofBadRequest("请输入学号/教师号");
        }
        String encodepwd = passwordEncoder.encode(model.getPassword());
        model.setPassword(encodepwd);
        model.setRoles("Studen");
        model.setCreatedDate(System.currentTimeMillis());
        Account account = getRepository().saveAndFlush(model);
        return account;
    }

    private void checkByAdd(Account model) {
        if (!StringUtils.isEmpty(model.getUsername())) {
            Account byUsername = repository.findAccountByUsername(model.getUsername());
            if (byUsername != null) {
                throw BaseException.ofBadRequest("此用户名已存在");
            }
        }

        if (!StringUtils.isEmpty(model.getTel())) {
            Account account = repository.findAccountByTel(model.getTel());
            if (account != null) {
                throw BaseException.ofBadRequest("此手机号已被注册");
            }
        }
        if (!StringUtils.isEmpty(model.getEmail())) {
            Account account = repository.findAccountByEmail(model.getEmail());
            if (account != null) {
                throw BaseException.ofBadRequest("此邮箱已被注册");
            }
        }
    }

    // username email phont
    public void checkByUpdate(Account curr, Account newAcc) {
        if (!StringUtils.isEmpty(newAcc.getUsername()) && !ObjectEx.equals(curr.getUsername(), newAcc.getUsername())) {
            Account account = repository.findAccountByUsername(newAcc.getUsername());
            if (account != null && !account.getId().equals(curr.getId())) {
                throw BaseException.ofBadRequest("此用户名已存在");
            }
        }

        if (!StringUtils.isEmpty(newAcc.getTel()) && !ObjectEx.equals(curr.getTel(), newAcc.getTel())) {
            Account account = repository.findAccountByTel(newAcc.getTel());
            if (account != null && !account.getId().equals(curr.getId())) {
                throw BaseException.ofBadRequest("此手机号已被注册");
            }
        }
        if (!StringUtils.isEmpty(newAcc.getEmail()) && !ObjectEx.equals(curr.getEmail(), newAcc.getEmail())) {
            Account account = repository.findAccountByEmail(newAcc.getEmail());
            if (account != null && !account.getId().equals(curr.getId())) {
                throw BaseException.ofBadRequest("此邮箱已被注册");
            }
        }
    }

    @Override
    public Account update_exec(Account model) {
//        model.setDisabled(true);
        model.setUpdateDate(System.currentTimeMillis());

        var save = getRepository().save(model);
        return save;
    }

    public AuthTokenDV login(LoginPara loginPara) {
//        List<Account> accounts = findByNameOrEmailOrPhone(loginPara.getUsername());
        List<Account> accounts = findByNameOrId(loginPara.getUsername());
        if (accounts == null || accounts.size() == 0) {
            throw BaseException.ofBadRequest("用户名或密码不正确");
        }
        Account r = accounts.get(0);
        if (r == null || !passwordEncoder.matches(loginPara.getPassword(), r.getPassword())) {
            throw BaseException.ofBadRequest("密码或者用户名不正确");
        }

        r.setLastLoginDate(System.currentTimeMillis());
        getRepository().save(r);

        long expiration = loginPara.getRememberMe() ? jwtConfiguration.getSessionTime_remember_me() : jwtConfiguration.getSessionTime();
        String token = Jwts.builder()
                .setSubject(r.getUsername())
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .signWith(SignatureAlgorithm.HS512, jwtConfiguration.secret)
                .compact();
        AuthTokenDV authTokenDV = new AuthTokenDV();
        authTokenDV.setAuthorization(jwtConfiguration.jwt_prefix + " " + token);
        return authTokenDV;
    }



//    public AuthTokenDV login2(LoginPara loginPara) {
//        List<Account> accounts = findByUsernameOrId(loginPara.getUsername()); //名称查询
//        if (accounts == null || accounts.size() == 0) {  // 是否存在用户
//            throw BaseException.ofBadRequest("用户名不正确");
//        }
//        Account r = accounts.get(0);
//        if (r == null || !passwordEncoder.matches(loginPara.getPassword(), r.getPassword())) { // 匹配密码
//            throw BaseException.ofBadRequest("密码不正确");
//        }
//        long expiration = jwtConfiguration.getSessionTime();
//        String token = Jwts.builder()
//                .setSubject(r.getUsername())
//                .setExpiration(new Date(System.currentTimeMillis() + expiration))
//                .signWith(SignatureAlgorithm.HS512, jwtConfiguration.secret)
//                .compact(); // 构建JWT凭证，用于后续操作
//        AuthTokenDV authTokenDV = new AuthTokenDV();
//        authTokenDV.setAuthorization(jwtConfiguration.jwt_prefix + " " + token);
//        return authTokenDV;
//    }



}
